#include "debugger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 读取源码文件内容
char** read_source_file(const char* filename, int* line_count) {
    FILE* file = fopen(filename, "r");
    if (!file) {
        printf("无法打开源码文件: %s\n", filename);
        return NULL;
    }
    
    char** lines = NULL;
    char buffer[1024];
    int count = 0;
    size_t capacity = 100;
    
    lines = malloc(sizeof(char*) * capacity);
    if (!lines) {
        fclose(file);
        return NULL;
    }
    
    while (fgets(buffer, sizeof(buffer), file)) {
        // 移除行尾的换行符
        size_t len = strlen(buffer);
        if (len > 0 && buffer[len-1] == '\n') {
            buffer[len-1] = '\0';
        }
        
        if (count >= capacity) {
            capacity *= 2;
            char** new_lines = realloc(lines, sizeof(char*) * capacity);
            if (!new_lines) {
                // 释放已分配的内存
                for (int i = 0; i < count; i++) free(lines[i]);
                free(lines);
                fclose(file);
                return NULL;
            }
            lines = new_lines;
        }
        
        lines[count] = malloc(strlen(buffer) + 1);
        if (!lines[count]) {
            // 释放已分配的内存
            for (int i = 0; i < count; i++) free(lines[i]);
            free(lines);
            fclose(file);
            return NULL;
        }
        strcpy(lines[count], buffer);
        count++;
    }
    
    fclose(file);
    *line_count = count;
    return lines;
}

// 释放源码文件内容
void free_source_file(char** lines, int line_count) {
    if (lines) {
        for (int i = 0; i < line_count; i++) {
            free(lines[i]);
        }
        free(lines);
    }
}

// 打印源码行号、内容和对应地址
void print_source_with_addresses(debugger_t *dbg, const char* source_filename) {
    printf("\n=== 源码行号与内存地址映射 ===\n");
    
    // 读取源码文件
    int line_count;
    char** source_lines = read_source_file(source_filename, &line_count);
    if (!source_lines) {
        printf("无法读取源码文件: %s\n", source_filename);
        return;
    }
    
    printf("文件: %s (共 %d 行)\n", source_filename, line_count);
    printf("行号 | 内存地址    | 源码内容\n");
    printf("-----|-------------|----------------------------------------\n");
    
    // 遍历每一行源码，查找对应的内存地址
    for (int line_num = 1; line_num <= line_count; line_num++) {
        uintptr_t addr = debugger_find_address_by_line(dbg, source_filename, line_num);
        
        // 获取源码行内容（注意：行号从1开始，数组索引从0开始）
        const char* line_content = (line_num <= line_count) ? source_lines[line_num-1] : "[超出文件范围]";
        
        // 清理行内容，移除前导空格
        const char* cleaned_content = line_content;
        while (isspace((unsigned char)*cleaned_content)) cleaned_content++;
        
        if (addr != 0) {
            printf("%4d | 0x%08lx | %s\n", line_num, addr, cleaned_content);
        } else {
            printf("%4d | (无映射)    | %s\n", line_num, cleaned_content);
        }
    }
    
    free_source_file(source_lines, line_count);
    printf("=== 源码映射完成 ===\n\n");
}

void test_dwarf_integration() {
    printf("=== DWARF集成测试 ===\n");
    
    debugger_t *dbg = debugger_create();
    if (!dbg) {
        printf("创建调试器失败\n");
        return;
    }
    
    // 测试DWARF功能
    if (debugger_load_dwarf_info(dbg, "./test_program") == 0) {
        printf("✓ DWARF信息加载成功\n");
        
        // 测试行号到地址的映射
        uintptr_t addr = debugger_find_address_by_line(dbg, "test_program.c", 10);
        if (addr != 0) {
            printf("✓ 行号到地址映射成功: test_program.c:10 -> 0x%lx\n", addr);
        } else {
            printf("✗ 行号到地址映射失败\n");
        }
        
        // 测试地址到行号的映射
        char filename[256];
        unsigned int line;
        if (debugger_find_line_by_address(dbg, addr, filename, sizeof(filename), &line) == 0) {
            printf("✓ 地址到行号映射成功: 0x%lx -> %s:%u\n", addr, filename, line);
        } else {
            printf("✗ 地址到行号映射失败\n");
        }
        
        // 打印所有源码行号与内存地址的映射
        print_source_with_addresses(dbg, "test_program.c");
    } else {
        printf("✗ DWARF信息加载失败\n");
    }
    
    debugger_destroy(dbg);
    printf("=== DWARF集成测试完成 ===\n\n");
}

void test_debugger_with_dwarf() {
    printf("=== 调试器与DWARF集成测试 ===\n");
    
    debugger_t *dbg = debugger_create();
    if (!dbg) {
        printf("创建调试器失败\n");
        return;
    }
    
    char *argv[] = {"./test_program", NULL};
    if (debugger_launch(dbg, "./test_program", argv) == 0) {
        printf("✓ 调试器启动成功\n");
        
        // 测试DWARF功能 - 手动加载DWARF信息
        if (debugger_load_dwarf_info(dbg, "./test_program") == 0) {
            printf("✓ DWARF表加载成功\n");
            
            // 测试几个关键行号的映射
            unsigned int test_lines[] = {5, 10, 15, 20};
            for (int i = 0; i < 4; i++) {
                uintptr_t addr = debugger_find_address_by_line(dbg, "test_program.c", test_lines[i]);
                if (addr != 0) {
                    printf("  test_program.c:%u -> 0x%lx\n", test_lines[i], addr);
                } else {
                    printf("  test_program.c:%u -> 未找到映射\n", test_lines[i]);
                }
            }
        } else {
            printf("✗ DWARF表加载失败\n");
        }
        
        debugger_detach(dbg);
    } else {
        printf("✗ 调试器启动失败\n");
    }
    
    debugger_destroy(dbg);
    printf("=== 调试器与DWARF集成测试完成 ===\n\n");
}

int main() {
    printf("开始DWARF功能测试...\n\n");
    
    test_dwarf_integration();
    test_debugger_with_dwarf();
    
    printf("所有测试完成！\n");
    return 0;
}